package com.yhh.college_information_platform.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yhh.college_information_platform.entity.Category;
import com.yhh.college_information_platform.entity.Resource;
import com.yhh.college_information_platform.entity.User;
import com.yhh.college_information_platform.mapper.CategoryMapper;
import com.yhh.college_information_platform.mapper.ResourceMapper;
import com.yhh.college_information_platform.mapper.UserMapper;
import com.yhh.college_information_platform.service.StatisticsService;
import com.yhh.college_information_platform.vo.ResourceVO;
import com.yhh.college_information_platform.vo.StatisticsVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 统计Service实现类
 *
 * @author yhh
 * @date 2025-10-26
 */
@Slf4j
@Service
public class StatisticsServiceImpl implements StatisticsService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Override
    public StatisticsVO getSystemStatistics() {
        StatisticsVO statistics = new StatisticsVO();

        // 1. 基础统计数据
        statistics.setTotalUsers(userMapper.selectCount(null));
        statistics.setTotalResources(resourceMapper.selectCount(null));

        // 待审核资料数
        LambdaQueryWrapper<Resource> pendingWrapper = new LambdaQueryWrapper<>();
        pendingWrapper.eq(Resource::getStatus, 0);
        statistics.setPendingResources(resourceMapper.selectCount(pendingWrapper));

        // 2. 今日新增数据
        LocalDateTime todayStart = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        LocalDateTime todayEnd = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);

        LambdaQueryWrapper<User> todayUserWrapper = new LambdaQueryWrapper<>();
        todayUserWrapper.between(User::getCreateTime, todayStart, todayEnd);
        statistics.setTodayNewUsers(userMapper.selectCount(todayUserWrapper));

        LambdaQueryWrapper<Resource> todayResourceWrapper = new LambdaQueryWrapper<>();
        todayResourceWrapper.between(Resource::getCreateTime, todayStart, todayEnd);
        statistics.setTodayNewResources(resourceMapper.selectCount(todayResourceWrapper));

        // 3. 总下载量、浏览量、点赞数
        List<Resource> allResources = resourceMapper.selectList(null);
        long totalDownloads = allResources.stream()
                .mapToLong(r -> r.getDownloadCount() != null ? r.getDownloadCount() : 0)
                .sum();
        long totalViews = allResources.stream()
                .mapToLong(r -> r.getViewCount() != null ? r.getViewCount() : 0)
                .sum();
        long totalLikes = allResources.stream()
                .mapToLong(r -> r.getLikeCount() != null ? r.getLikeCount() : 0)
                .sum();

        statistics.setTotalDownloads(totalDownloads);
        statistics.setTotalViews(totalViews);
        statistics.setTotalLikes(totalLikes);

        // 4. 用户增长趋势（最近7天）
        statistics.setUserTrend(getUserTrend());

        // 5. 资料增长趋势（最近7天）
        statistics.setResourceTrend(getResourceTrend());

        // 6. 分类资料统计
        statistics.setCategoryStats(getCategoryStats());

        // 7. 热门资料Top10
        statistics.setHotResources(getHotResources());

        log.info("获取系统统计数据成功");
        return statistics;
    }

    /**
     * 获取用户增长趋势
     */
    private List<Map<String, Object>> getUserTrend() {
        List<Map<String, Object>> trend = new ArrayList<>();

        for (int i = 6; i >= 0; i--) {
            LocalDate date = LocalDate.now().minusDays(i);
            LocalDateTime dayStart = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime dayEnd = LocalDateTime.of(date, LocalTime.MAX);

            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.between(User::getCreateTime, dayStart, dayEnd);
            Long count = userMapper.selectCount(wrapper);

            Map<String, Object> data = new HashMap<>();
            data.put("date", date.toString());
            data.put("count", count);
            trend.add(data);
        }

        return trend;
    }

    /**
     * 获取资料增长趋势
     */
    private List<Map<String, Object>> getResourceTrend() {
        List<Map<String, Object>> trend = new ArrayList<>();

        for (int i = 6; i >= 0; i--) {
            LocalDate date = LocalDate.now().minusDays(i);
            LocalDateTime dayStart = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime dayEnd = LocalDateTime.of(date, LocalTime.MAX);

            LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
            wrapper.between(Resource::getCreateTime, dayStart, dayEnd);
            Long count = resourceMapper.selectCount(wrapper);

            Map<String, Object> data = new HashMap<>();
            data.put("date", date.toString());
            data.put("count", count);
            trend.add(data);
        }

        return trend;
    }

    /**
     * 获取分类资料统计
     */
    private List<Map<String, Object>> getCategoryStats() {
        List<Map<String, Object>> stats = new ArrayList<>();

        // 获取所有一级分类
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Category::getParentId, 0);
        wrapper.orderByAsc(Category::getId);
        List<Category> categories = categoryMapper.selectList(wrapper);

        log.info("获取到一级分类数量: {}", categories.size());

        for (Category category : categories) {
            // 获取该一级分类下的所有二级分类ID
            LambdaQueryWrapper<Category> subWrapper = new LambdaQueryWrapper<>();
            subWrapper.eq(Category::getParentId, category.getId());
            List<Category> subCategories = categoryMapper.selectList(subWrapper);
            
            long count = 0;
            
            log.info("一级分类[{}]，ID: {}，子分类数量: {}", category.getName(), category.getId(), 
                    subCategories != null ? subCategories.size() : 0);
            
            // 如果有二级分类，统计二级分类下的资料数
            if (subCategories != null && !subCategories.isEmpty()) {
                for (Category subCategory : subCategories) {
                    LambdaQueryWrapper<Resource> resourceWrapper = new LambdaQueryWrapper<>();
                    resourceWrapper.eq(Resource::getCategoryId, subCategory.getId());
                    resourceWrapper.eq(Resource::getStatus, 1); // 只统计已审核通过的
                    Long subCount = resourceMapper.selectCount(resourceWrapper);
                    count += subCount;
                    log.info("  二级分类[{}]，ID: {}，资料数: {}", subCategory.getName(), subCategory.getId(), subCount);
                }
            } else {
                // 如果没有二级分类，直接统计该分类下的资料
                LambdaQueryWrapper<Resource> resourceWrapper = new LambdaQueryWrapper<>();
                resourceWrapper.eq(Resource::getCategoryId, category.getId());
                resourceWrapper.eq(Resource::getStatus, 1); // 只统计已审核通过的
                count = resourceMapper.selectCount(resourceWrapper);
                log.info("  该分类无子分类，直接统计资料数: {}", count);
            }

            log.info("一级分类[{}]总资料数: {}", category.getName(), count);

            Map<String, Object> data = new HashMap<>();
            data.put("name", category.getName());
            data.put("count", count);
            stats.add(data);
        }

        log.info("分类统计结果: {}", stats);
        return stats;
    }

    /**
     * 获取热门资料Top10
     */
    private List<ResourceVO> getHotResources() {
        LambdaQueryWrapper<Resource> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resource::getStatus, 1); // 只查询已审核通过的
        wrapper.orderByDesc(Resource::getDownloadCount);
        wrapper.last("LIMIT 10");

        List<Resource> resources = resourceMapper.selectList(wrapper);

        return resources.stream().map(resource -> {
            ResourceVO vo = new ResourceVO();
            BeanUtils.copyProperties(resource, vo);
            return vo;
        }).collect(Collectors.toList());
    }
}

